/*-------------------------------------------------------------------------
 - Copyright (c) 2024-2025 [XD-AMCC TEAM]
 - [XD-AMCC] is licensed under Mulan PSL v2.
 - You can use this software according to the terms and conditions of the Mulan PSL v2.
 - You may obtain a copy of Mulan PSL v2 at:
 -          http://license.coscl.org.cn/MulanPSL2
 - THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES
 - OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 - TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 - See the Mulan PSL v2 for more details.
 ------------------------------------------------------------------------*/


/**
 * @file
 * @brief Interface of class parse-tree, tree-walker, tree-map
 *        and some related auxiliary classes.
 *
 * @author  WXQ#XDU
 * @date    2024.11
 */

#pragma once

#ifndef AMCC_TREE_H
#define AMCC_TREE_H

#include <string.h>

#include "amcc_config.h"
#include "amcc_list.h"
#include "token.h"

AMCC_DECL_BEGIN


/**
 * @brief Type of functions to release an annotation.
 *
 * Annotations, or attributes, refer to the semantics of a
 * construct, and can be attached to tree nodes.
 *
 * @param pAnnotation   pointer to annotation within a tree node,
 *                      and NULL(0) should be accepted
 *
 * @see TREEFUNC_SET_free_annotation()
*/
typedef void (*t_treefunc_free_annotation)(void * pAnnotation);

/**
 * @brief Set the annotation de-allocator.
 *
 * The de-allocator will be invoked during destroy a parse tree.
 *
 * @param newHandler  pointer to a function which deallocate annotation
 * @return Return the last de-allocator before this call.
 */
extern t_treefunc_free_annotation
TREEFUNC_SET_free_annotation(t_treefunc_free_annotation newHandler);


/** Named constants that identify all Non-Terminals of AMC grammar */
typedef enum NonTerminalId {

    #define  GRAM_NT_DEF(nt, n1, n2)  NT_##nt  // let a name like NT_expr, NT_statement
    #include "../meta/_gramsymbol.inc"
    #undef   GRAM_NT_DEF

} EnumNonTerminal;


/**
 * @brief Type of non-terminals of AMC grammar.
 *
 * An instance of this type is a specific non-terminal with
 * an internal number and name text.
 *
 * These instances are used to mark non-leaf nodes of
 * a parse tree for AMC program.
 */
typedef struct non_terminal_def {
    EnumNonTerminal   ntId;   //!< enumerated id of non-terminal
    const char *      ntName; //!< text of non-terminal
} t_nonterminal, * t_nonterminal_ptr;


struct symtable_entry;  // struct of a symbol-table-entry

/**
 * @brief Type of terminals of AMC grammar.
 *
 * <br/>Terminals are used to mark leaf nodes of a parse tree.
 *
 * <p/>Because a terminal in grammar just is a token-kind-name
 * without any other information, so AMCC uses a (token, symbol-entry) pair
 * as an instance of a terminal.
 *
 * <p/>Only identifiers have their symbol entry.
 * <p/>
 * (1) If tokenPtr points to a name definition (such as function, variable,
 *     or label), the corresponding symbol entry is created,
 *     put into a symbol table, and the entry address is also stored to here.
 * <p/>
 * (2) If tokenPtr points to a name reference (using point), AMCC
 *     finds this name in symbol tables, and copy the entry address to here.
 */
typedef struct terminal_instance {

    /// Pointer to the token, aka an instance of a terminal
    t_token_ptr          tokenPtr;

    /// Pointer to the symbol-table-entry of an ID token,
    /// this field is filled during building symbol tables.
    struct symtable_entry * symEntryPtr;

} t_terminal, * t_terminal_ptr;


/**
 * @brief Query the definition item of a non-terminal.
 * @param id  non-terminal-id
 * @return Return a pointer to the definition item if found,
 *         otherwise return NULL.
 */
extern t_nonterminal_ptr nonterm_query_define(EnumNonTerminal id);

/**
 * @brief Query the text of a non-terminal.
 * @param id  non-terminal-id
 * @return Return the text of non-terminal if found, otherwise return
 *         a built-in text.
 */
extern const char * nonterm_query_name(EnumNonTerminal id);


#define PRD_ID_UNKNOWN     0xFFFF       // Invalid productionId

/**
 * @brief Type of grammar-symbol instance which marks a parse tree node.
 *
 * All attributes MUST be accessed through API functions.
 */
typedef struct parsetree_marker {

    /// For a parent tree node, the field 'productionId' indicates
    ///    the production used to left-most derivation in top-down parsing.
    /// Also, 'productionId' is indicating
    ///   "Whether the node is leaf in the parse tree of a sentence".
    /// <br/>
    /// - If productionId == PRD_ID_UNKNOWN, congratulations,
    ///      you have encountered a BUG of AMCC parser.
    ///      Welcome to your reports.<br/>
    /// - If productionId > 0, this node is non-leaf and marked
    ///      by a non-terminal.<br/>
    /// - If productionId < 0, this node is leaf and marked
    ///      by a token(terminal instance).<br/>
    /// - If productionId == 0, this node is leaf and marked
    ///      by the EPSILON.
    int   productionId;

    /// Field 'instance' is the marker of a tree node.
    union  {
        /// A non-terminal MUST mark a non-leaf node (productionId > 0)
        t_nonterminal_ptr nonTerminal;

        /// A terminal MUST mark a leaf node (productionId < 0)
        /// NOTICE: this field is also used to record an EPSILON symbol.
        t_terminal_ptr terminal;
    } instance;

} t_tree_marker , * t_tree_marker_ptr;

typedef struct tree_basic_operations t_tree_basic_operations;

// Placeholder for type of annotations.
// An annotation is attached to a tree node in semantic analysis.
typedef void *  t_annotation_ptr;

/**
 * @brief Basic structure of parse tree node.
 *
 * All attributes MUST be accessed through API functions.
 */
typedef struct tree_basic {

    struct tree_basic * parent;     //!< pointer to parent node

    /// List of all children of this node, the underlay type is t_list<tree_basic*>
    /// In concept, this list is an instance of the right part of a production.
    t_list_ptr          children;

    /// node marker, it may be non-terminal, terminal, or epsilon
    t_tree_marker       marker;

    /// the start position of the input construct represented
    /// by a tree which root is this node
    t_position   startPosition;

    /// the stop position of the input construct represented
    /// by a tree which root is this node
    t_position   stopPosition;

    /**
     * @brief Annotation attached to this node.
     *     The type and storage of annotations is owned, defined by the
     *     semantic analysis module.
     * @note Caller can invoke TREEFUNC_SET_free_annotation() to set
     *       the function which destroys annotation.
     * @note Parser never access this field.
     */
    t_annotation_ptr pAnnotation;

} t_tree, * t_tree_ptr;


// -----------------------------------------------------------------------
/// @name API of class tree
/// @{


/**
 * @brief Destroy whole tree.
 * @param root    pointer to the root of tree
 */
extern void tree_destroy(t_tree_ptr root);

/**
 * @brief Destroy whole tree with log.
 * @param pThis   pointer to the root of tree
 */
extern void parse_tree_destroy(t_tree_ptr pThis);

/**
 * @brief  Dump tree into a file which path is defined by
 *         amcc_get_treeFilePath().
 *
 * @param pThis    pointer to the root of tree
 * @see amcc_get_treeFilePath()
*/
extern void tree_dump(t_tree_ptr  pThis);

/**
 * @brief  Whether this tree node is a leaf now.
 * @param pThis  pointer to this node
 * @return Return true if this node hasn't any child.
 */
extern bool tree_is_leaf (t_tree_ptr pThis);

/**
 * @brief  Whether this node is a root node now.
 * @param pThis  pointer to this node
 * @return Return true if this node has no parent.
 */
extern bool tree_is_root (t_tree_ptr pThis);

/**
 * @brief Get the parent node of this node.
 * @param pThis  pointer to this node
 * @return Return the parent node of this node.
 */
extern t_tree_ptr tree_get_parent (t_tree_ptr pThis);

/**
 * @brief Get the number of children nodes.
 * @param pThis  pointer to this node
 * @return Return the number of children nodes.
 * @note If this node is a leaf, this func MUST return 0.
 */
extern int  tree_get_childCount (t_tree_ptr pThis);

/**
 * @brief  Get a special child node of this node.
 * @param pThis  pointer to this node
 * @param index  subscript of the child, starting from 0
 *
 * @return Return the child node which subscript is index.
 * @return Return NULL if the index is out of range.
 */
extern t_tree_ptr tree_get_child (t_tree_ptr pThis,  int index);

/**
 * @brief Get all children of this node as a list.
 * @param pThis  pointer to this node
 * @return Return a pointer to the list of all children of this node.
 */
extern t_list_ptr tree_get_children (t_tree_ptr pThis);

/**
 * @brief Get the production-id for a non-terminal marked node.
 *
 * @param pThis pointer to this node
 * @return  Return a positive integer if isNonTerminal() returns true,
 *   return a negative integer if isTerminal() returns true,
 *   return zero if isEpsilon() returns true.
 */
extern int  tree_get_productionId (t_tree_ptr pThis);


/**
 * @brief Whether this tree node is marked by a non-terminal.
 * @param pThis  pointer to this node in tree
 * @return Return true if this node is marked by a non-terminal.
 * @return Return false if this node is marked by a terminal or epsilon.
 */
extern bool tree_is_nonTerminal (t_tree_ptr pThis);

/**
 * @brief  Whether this node is marked by EPSILON.
 * @param pThis  pointer to this node
 * @return Return true if this node is marked by EPSILON.
 */
extern bool tree_is_epsilon (t_tree_ptr pThis);


/**
 * @brief Whether this tree node is marked by a terminal.
 * @param pThis  pointer to this node in tree
 * @return Return true if this node is marked by a terminal,
 *    and so, this node MUST be a leaf node.
 * @return Return false if this node is marked by a non-terminal,
 *    and so, this node MUST be a non-leaf node.
 */
extern bool tree_is_terminal (t_tree_ptr pThis);

/**
 * @brief Whether this tree node is marked with an identifier.
 * @param pThis   pointer to this node in tree
 * @return Return true only if this node marked with an identifier.
 */
extern bool tree_is_identifier (t_tree_ptr pThis);

/**
 * @brief Whether this tree node is marked with a type name.
 * @param pThis   pointer to this node in tree
 * @return Return true only if this node is marked with a type name.
 */
extern bool tree_is_typeName (t_tree_ptr pThis);

/**
 * @brief Whether this tree node is marked with a function name
 *        and this is the definition.
 * @param pThis   pointer to this node in tree
 * @return Return true only if this node is marked with a function
 *         name and this is the definition.
 * @note A func-name may occur in a func-declaration or a function call.
 */
extern bool tree_is_funcNameDefinition (t_tree_ptr pThis);

/**
 * @brief Whether this tree node is marked with a function name
 *        and this is a reference.
 * @param pThis   pointer to this node in tree
 * @return Return true only if this node is marked with a function
 *         name, and it is in an expression.
 * @note A func-name may occur in a func-declaration or a function call.
 */
extern bool tree_is_funcNameReference (t_tree_ptr pThis);

/**
 * @brief Whether this tree node is marked with a function name
 *        and this is the non-definition declaration.
 * @param pThis   pointer to this node in tree
 * @return Return true only if this node is marked with a function
 *         name and this is the non-definition declaration.
 * @note A func-name may occur in a func-declaration, or a function call.
 */
extern bool tree_is_funcNameNonDefinition (t_tree_ptr pThis);

/**
 * @brief Whether this tree node is marked with a variable/array
 *        name and this is a definition.
 * @param pThis   pointer to this node in tree
 * @return Return true only if this node is marked with a
 *         variable/array name, and it is in definition.
 * @note A var-name may occur in a var-declaration,
 *       a parameter-declaration, or in an expression.
 */
extern bool tree_is_varNameDefinition (t_tree_ptr pThis);

/**
 * @brief Whether this tree node is marked with a variable/array
 *        name and this is a reference.
 * @param pThis   pointer to this node in tree
 * @return Return true only if this node is marked with a
 *         variable/array name, and it is in an expression.
 * @note A var-name may occur in a var-declaration,
 *       a parameter-declaration, or an expression.
 */
extern bool tree_is_varNameReference (t_tree_ptr pThis);

/**
 * @brief Whether this tree node is marked with a label name
 *        for "goto label" and this is a definition.
 * @param pThis   pointer to this node in tree
 * @return Return true only if this node is marked with a
 *         label name, and it is in definition.
 * @note A label-name may occur in a label-declaration or
 *       a "goto" statement.
 */
extern bool tree_is_labelNameDefinition (t_tree_ptr pThis);

/**
 * @brief Whether this tree node is marked with a label name
 *        and this is a reference in "goto" statement.
 * @param pThis   pointer to this node in tree
 * @return Return true only if this node is marked with a
 *         label name, and it is in "goto" statement.
 * @note A label-name may occur in a label-declaration or
 *       a "goto" statement.
 */
extern bool tree_is_labelNameReference (t_tree_ptr pThis);

/**
 * @brief Get the node marker, a grammar symbol marked this node.
 *
 * @param pThis  pointer to this node
 * @return Return a pointer to the grammar symbol marked this node.
 */
extern t_tree_marker_ptr tree_get_marker (t_tree_ptr pThis);

/**
 * @brief Get the text of node marker, aka the grammar symbol marked this node.
 *
 * @param pThis  pointer to this node
 * @return If this node is marked with a non-terminal,
 *         return the name of this non-terminal.
 * @return If this node is marked with a terminal(token),
 *         return the input text of this token.
 * @return If this node is marked with EPSILON(non-token),
 *         return the macro EPSILON_TEXT.
 */
extern const char * tree_get_markText (t_tree_ptr pThis);

/**
 * @brief Get the non-terminal marked this node.
 * @param pThis  pointer to this node
 * @return Return a pointer to the non-terminal marked this node
 *         ONLY if isNonTerminal() is true.
 * @return Return null if isNonTerminal() is false.
 */
extern t_nonterminal_ptr tree_get_nonTerminal (t_tree_ptr pThis);

/**
 * @brief Get the terminal marked this node.
 * @param pThis  pointer to this node
 * @return Return a pointer to the terminal marked this node
 *         ONLY if isNonTerminal() is false.
 * @return Return null if isNonTerminal() is true.
 */
extern t_terminal_ptr tree_get_terminal (t_tree_ptr pThis);

/**
 * @brief Whether the marker of node is the specified non-terminal.
 * @param pThis  pointer to this node in tree
 * @param nt     non-terminal
 * @return Return true if this node is marked by non-terminal "nt".
 */
extern bool tree_is_markedByNT(t_tree_ptr pThis, EnumNonTerminal nt);

/**
 * @brief Whether the marker of node is the specified terminal.
 * @param pThis  pointer to this node in tree
 * @param tk     terminal(token kind)
 * @return Return true if this node is marked by terminal "tk".
 */
extern bool tree_is_markedByToken(t_tree_ptr pThis, EnumTokenKind tk);


/**
 * @brief Get the marked token in this node.
 * @param pThis  pointer to this node in tree
 * @return Return a pointer to the token in this node ONLY
 *         if isTerminal(pThis) is true.
 * @return Return null if isTerminal() is false.
 */
extern t_token_ptr tree_get_token (t_tree_ptr pThis);

/**
 * @brief Get the marked terminal (token kind) in this node.
 * @param pThis  pointer to this node in tree
 * @return Return the token kind if isTerminal(pThis) is true,
 *         otherwise, return TK_ERROR.
 */
extern EnumTokenKind  tree_get_tokenKind (t_tree_ptr pThis);

/**
 * @brief Get the start position of the input construct represented by this node.
 *
 * @param pThis pointer to this node
 * @return The start position of first token of the structure.
 */
extern t_position tree_get_startPosition (t_tree_ptr pThis);

/**
 * @brief Get the stop position of the input construct represented by this node.
 *
 * @param pThis pointer to this node
 * @return The end position of last token of the syntax structure.
 */
extern t_position tree_get_stopPosition(t_tree_ptr pThis);

/**
 * @brief Get the symbol entry of an ID-marked node.
 * @param pThis pointer to this node
 * @return Return the symbol entry if isTerminal(pThis) is true and
 *         this node is marked with a name,
 *         otherwise return null.
 */
extern struct symtable_entry * tree_get_symbolEntry (t_tree_ptr pThis);

/**
 * @brief (re)Set the symbol entry of an ID-marked node.
 *
 * This function is used only if isTerminal(pThis) is true and
 * this node is marked with a name.
 *
 * @param pThis pointer to this node
 * @param entry pointer to the new symbol entry
 */
extern void  tree_set_symbolEntry (t_tree_ptr pThis,
                                   struct symtable_entry * entry);

/**
 * @brief Get the annotation attached to this node.
 * @param pThis pointer to this node
 * @return Return the annotation attached to this node.
 */
extern t_annotation_ptr  tree_get_annotation (t_tree_ptr pThis);

/**
 * @brief (re)Set the annotation attached to this node.
 *
 * @param pThis pointer to this node
 * @param pAnnotation pointer to the new annotation
 * @return Return a pointer to last annotation attached to this node.
 */
extern t_annotation_ptr  tree_set_annotation (t_tree_ptr pThis,
                                              t_annotation_ptr pAnnotation);

/// @}
// -----------------------------------------------------------------------


// -----------------------------------------------------------------------
/// @name API of class tree-walker
/// @{

//
//   This API defines a NB generic tree-traversal framework, and
//   is used in tree-dump and
//   all works based on "Syntax Directed Translation" in AMCC.
//

/**
 * @brief  Abstract parse-tree listener.
 *
 * This class and its derived classes supply a set of access operations
 *     to tree nodes.
 * All instances of these classes are used by tree_walk().
 *
 * For creating a new listener object, caller MUST call
 *     tree_listener_init0() firstly,
 * and then override one or more member functions in derived class.
 *
 * @see tree_listener_init0()
 * @see tree_walk()
 * @see tree_dump()
 */
typedef struct tree_listener  t_tree_listener, * t_tree_listener_ptr;

/**
 * @brief Initialize a listener to a default init-value,
 *        all default operation do nothing.
 * <p/>
 *
 * After calling this function, the caller should override one or more
 * member functions of tree_listener with your version.
 *
 * @param pThis  pointer to the listener
 * @param sizeOfListener  size of the real listener object
*/
extern void tree_listener_init0(t_tree_listener_ptr pThis, size_t sizeOfListener);

/**
 * @brief Performs a depth-first traversal on a parse tree
 *        in recursive manner.
 *
 * @param tree  pointer to the root node of tree
 * @param listenerPtr  pointer to the listener
 */
extern void tree_walk(t_tree_ptr  tree, t_tree_listener_ptr listenerPtr);


/** Function type to visit tree node based on tree-listener and tree_walk()  */
typedef void (* t_treefunc_visitnode) (t_tree_listener_ptr pThis, t_tree_ptr node);

struct tree_listener {

    /**
     * @brief Depth of current node.
     * @note The depth of tree root is 1.
     * @note This field is ONLY modified in tree_walk().
     */
    /*public*/ int   depthCounter;

    /**
     * @brief  Common pre-action that is called just before visit
     *         this node and its sub-nodes.
     * @param pThis  pointer to this listener
     * @param node  pointer to the node to be visited immediately
     * @note  The default version is do nothing.
     */
    void (* enterEveryNode) (t_tree_listener_ptr pThis, t_tree_ptr node);
    /**
     * @brief  Common post-action that is called immediately after this node
     *         and its sub-nodes are visited.
     *
     * @param pThis  pointer to this listener
     * @param node  pointer to the node that have just been visited
     * @note  The default version is do nothing.
     */
    void (* exitEveryNode)  (t_tree_listener_ptr pThis, t_tree_ptr node);

    /**
     * @brief  Action to visit a terminal-marked node (a leaf node).
     *
     * Before this action, enterEveryNode() has called, and
     *  after this action, exitEveryNode() is called immediately.
     *
     * @param pThis  pointer to this listener
     * @param node   pointer to the terminal-marked node
     * @note  The default version is do nothing.
     */
    void (* visitTerminalNode) (t_tree_listener_ptr pThis, t_tree_ptr node);

    /**
     * @brief  Action to visit an epsilon-marked node (a leaf node).
     *
     * Before this action, enterEveryNode() has called, and
     *  after this action, exitEveryNode() is called immediately.
     *
     * @param pThis  pointer to this listener
     * @param node   pointer to the epsilon-marked node
     * @note  The default version is do nothing.
     */
    void (* visitEpsilonNode) (t_tree_listener_ptr pThis, t_tree_ptr node);

    /**
     * @brief  Whether stop the traversal or not.
     *
     * If this function returns true, all remaining nodes that have not
     * been visited will no longer be accessed.
     *
     * @param pThis  pointer to this listener
     * @param node  pointer to the node to be visited immediately
     * @return Return true if the traversal must be stopped.
     * @note   The default version returns false.
     */
    bool (* isShouldStopVisit) (t_tree_listener_ptr pThis, t_tree_ptr node);
    /*private*/ bool  shouldStopVisit; // see isShouldStopVisit

    /**
     * @brief  Default pre-action that is called just before visit a
     *         non-terminal-marked node.
     *
     * This action is called only if entry_X(see below) is not defined.
     *
     * @param pThis  pointer to this listener
     * @param node  pointer to the non-terminal-marked node to be visited immediately
     * @note  The default version is do nothing.
     */
    void (* enterNonTerminalNode) (t_tree_listener_ptr pThis, t_tree_ptr node);
    /**
     * @brief  Default post-action that is called immediately after the
     *         non-terminal-marked node is visited.
     *
     * This action is called only if exit_X(see below) is not defined.
     *
     * @param pThis  pointer to this listener
     * @param node  pointer to the non-terminal-marked node that have just been visited
     * @note  The default version is do nothing.
     */
    void (* exitNonTerminalNode) (t_tree_listener_ptr pThis, t_tree_ptr node);

//
// For each non-terminal X of grammar, there is a pair of visit operations:
//
// (1)  entry_X(listener, node): pre-action for X productions.
//
//      Before visit a node marked with X and its children,
//      enterEveryNode() is called firstly, and then
//      entry_X() is called.
//  *** If and only if this function is null (not defined),
//      enterNonTerminalNode() will be called.
//  *** The default version is null (not defined).
//
// (2)  exit_X(listener, node): post-action for X productions.
//
//      After all children of a node marked with X are visited,
//      exit_X() is called firstly, and then
//      exitEveryNode() is called.
//  *** If and only if this function is null (not defined),
//      exitNonTerminalNode() will be called.
//  *** The default version is null (not defined).
//

#define  GRAM_NT_DEF(nt, n1, n2)  enter_##nt , exit_##nt

    t_treefunc_visitnode
    #include "../meta/_gramsymbol.inc"
    ;
#undef   GRAM_NT_DEF

};


/// @}
// -----------------------------------------------------------------------


// -----------------------------------------------------------------------
/// @name API of class tree-map
/// @{

//
// We design this generic collection to avoid modifying or affecting
// the annotation objects stored in a parse tree.
//
// In these collections, the key of elements is a pointer to a tree node,
// the value is some interesting semantic values (attributes)
// wrapped into an object.
//

#include "amcc_hashmap.h"

typedef t_hashmap_ptr   t_treemap_ptr;
typedef t_map_value     t_treemap_value;

/**
 * @brief Creates a new tree-map object.
 *
 * @param capacity_init minimal number of buckets to use on initialization
 * @param fpFree  pointer to a function which free bounded attribute object
 *
 * @return On success, return a pointer to the new created map.
 * @return On failure, just as memory allocation failure, return null.
 */
extern t_treemap_ptr treemap_new (unsigned capacity_init, t_mapfunc_free fpFree);

/**
 * @brief Cleans all entries and destroy the tree-map.
 * @param mapPtr  pointer to this tree-map
 */
extern void treemap_destroy(t_treemap_ptr mapPtr);

/**
 * @brief Gets the number of elements in the container.
 * @param mapPtr pointer to this map
 * @return The number of elements in the container.
 */
extern int  treemap_size(t_treemap_ptr mapPtr);

/**
 * @brief  Puts the bound of an attribute to tree node into tree-map.
 *
 * If the tree node is already exists in tree-map, this map keeps unchanged.
 *
 * @param mapPtr  pointer to this tree-map
 * @param node    pointer to a tree node
 * @param attribute  pointer to the attribute object
 */
extern void  treemap_put ( t_treemap_ptr mapPtr,
                           t_tree_ptr node , t_treemap_value attribute );

/**
 * @brief  Gets the bounded attribute object of the given node.
 * @param mapPtr  pointer to this tree-map
 * @param node    pointer to a tree node
 * @return Return the attribute if node is found in map, otherwise return null.
 */
extern t_treemap_value treemap_get(t_treemap_ptr mapPtr, t_tree_ptr node);

/**
 * @brief  Remove the bound of an attribute to tree node from tree-map.
 * @param mapPtr  pointer to this tree-map
 * @param node    pointer to a tree node
 */
extern void treemap_remove ( t_treemap_ptr mapPtr, t_tree_ptr node );


/// @}
// -----------------------------------------------------------------------


AMCC_DECL_END

#endif // #ifndef AMCC_TREE_H
